package com.javalab.recorder.ui;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.util.EventListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

import com.javalab.recorder.event.OptionsMenuItemClickEvent;
import com.javalab.recorder.event.PlaybackButtonClickEvent;
import com.javalab.recorder.event.RecordButtonClickEvent;
import com.javalab.recorder.event.StopButtonClickEvent;
import com.javalab.recorder.listener.EventDispatcher;
import com.javalab.recorder.listener.OptionsMenuItemClickEventListener;
import com.javalab.recorder.listener.PlaybackButtonClickEventListener;
import com.javalab.recorder.listener.RecordButtonClickEventListener;
import com.javalab.recorder.listener.StopButtonClickEventListener;
import com.javalab.recorder.state.RecorderState;

public class MainFrame extends JFrame implements BaseUI {

	/**
	 *
	 */
	private static final long serialVersionUID = -1015076664754800451L;

	private JPanel contentPanel;

	private JMenuItem optionsMenuItem;

	private JButton recordButton;

	private JButton playbackButton;

	private JButton stopButton;

	private RecorderState recorderState;

	private EventDispatcher eventDispatcher = new EventDispatcher();

	public MainFrame() {
		contentPanel = new JPanel();
		getContentPane().add(contentPanel);

		initMenu();

		recordButton = initRecordButton();
		playbackButton = initPlaybackButton();
		stopButton = initStopButton();

		contentPanel.add(recordButton);
		contentPanel.add(stopButton);
		contentPanel.add(playbackButton);

		setSize(250, 97);
		setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - getSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height - getSize().height) / 2);
		setTitle("Recorder");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	/**
	 * Initialize a Record Button with action attached
	 * @return
	 */
	private JButton initRecordButton() {
		Action recordButtonAction = new AbstractAction() {
			private static final long serialVersionUID = -187393171570505894L;

			@Override
			public void actionPerformed(ActionEvent paramActionEvent) {
				RecordButtonClickEvent event = new RecordButtonClickEvent();
				event.setParent(MainFrame.this);
				event.setState(recorderState);
				for (RecordButtonClickEventListener listener : eventDispatcher.getListeners(RecordButtonClickEventListener.class)) {
					listener.handleActionEvent(event);
				}
			}
		};
		recordButtonAction.putValue(Action.NAME, "Record");
		JButton button = new JButton(recordButtonAction);
		return button;
	}

	/**
	 * Initialize a play back Button with action attached
	 * @return
	 */
	private JButton initPlaybackButton() {
		Action playbackButtonAction = new AbstractAction() {
			private static final long serialVersionUID = -187393171570505894L;

			@Override
			public void actionPerformed(ActionEvent paramActionEvent) {
				PlaybackButtonClickEvent event = new PlaybackButtonClickEvent();
				event.setParent(MainFrame.this);
				event.setState(recorderState);
				for (PlaybackButtonClickEventListener listener : eventDispatcher.getListeners(PlaybackButtonClickEventListener.class)) {
					listener.handleActionEvent(event);
				}
			}
		};
		playbackButtonAction.putValue(Action.NAME, "Play");
		JButton button = new JButton(playbackButtonAction);
		return button;
	}

	/**
	 * Initialize a stop button with action attached
	 * @return
	 */
	private JButton initStopButton() {
		Action stopButtonAction = new AbstractAction() {
			private static final long serialVersionUID = -187393171570505894L;

			@Override
			public void actionPerformed(ActionEvent paramActionEvent) {
				StopButtonClickEvent event = new StopButtonClickEvent();
				event.setParent(MainFrame.this);
				event.setState(recorderState);
				for (StopButtonClickEventListener listener : eventDispatcher.getListeners(StopButtonClickEventListener.class)) {
					listener.handleActionEvent(event);
				}
			}
		};
		stopButtonAction.putValue(Action.NAME, "Stop");
		JButton button = new JButton(stopButtonAction);
		return button;
	}

	private void initMenu() {
		JMenuBar menuBar = new JMenuBar();

		JMenu fileMenu = new JMenu("File");
		menuBar.add(fileMenu);

		JMenu editMenu = new JMenu("Tools");

		Action action = new AbstractAction() {
			private static final long serialVersionUID = -7450352500160612441L;

			@Override
			public void actionPerformed(ActionEvent paramActionEvent) {
				for (OptionsMenuItemClickEventListener listener : eventDispatcher.getListeners(OptionsMenuItemClickEventListener.class)) {
					listener.handleActionEvent(new OptionsMenuItemClickEvent());
				}
			}
		};
		action.putValue(Action.NAME, "Options");
		optionsMenuItem = new JMenuItem(action);
		editMenu.add(optionsMenuItem);

		menuBar.add(editMenu);

		setJMenuBar(menuBar);
	}


	private void resetButtonState() {
		recordButton.getAction().setEnabled(recorderState.isRecordButtonEnabled());
		playbackButton.getAction().setEnabled(recorderState.isPlaybackButtonEnabled());
		stopButton.getAction().setEnabled(recorderState.isStopButtonEnabled());
	}

	public RecorderState getRecorderState() {
		return recorderState;
	}


	public void setRecorderState(RecorderState recorderState) {
		this.recorderState = recorderState;
		resetButtonState();
	}

	@Override
	public void subscribeEvent(EventListener eventListener) {
		eventDispatcher.subscribeEvent(eventListener);
	}

	@Override
	public void unsubscribeEvent(EventListener eventListener) {
		eventDispatcher.unsubscribeEvent(eventListener);
	}

}
